import time
import threading
from typing import Dict, Any, Optional
from django.core.cache import cache
import hashlib
from .models import APIKey, RateLimit, ConversationSession
from django.conf import settings
import logging
logger = logging.getLogger(__name__)

# 全局配置
# API_KEY_LENGTH = 32
# TOKEN_EXPIRY_SECONDS = 3600
# RATE_LIMIT_MAX = 5  # 每分钟最大请求数
# RATE_LIMIT_INTERVAL = 60

# 线程锁用于速率限制
rate_lock = threading.Lock()
# 全局TopKLogSystem实例，避免重复初始化
_system_instance = None

def get_system_instance():
    """获取全局TopKLogSystem实例（单例模式）"""
    global _system_instance
    if _system_instance is None:
        from topklogsystem import TopKLogSystem
        _system_instance = TopKLogSystem(
            log_path="./data/log",
            llm="deepseek-r1:7b",
            embedding_model="bge-large:latest"
        )
    return _system_instance

#modifyed to supply messages
def deepseek_r1_api_call(messages: list[dict], use_workflow: bool = False) -> dict:
    """DeepSeek-R1 API 调用函数
    改进版：支持多轮上下文调用和工作流模式
    messages 格式: [{"role": "user"/"assistant"/"system", "content": "..."}]
    
    Returns:
        dict: 包含response和其他信息的字典
    """
    prompt = ""
    for msg in messages:
        role = "用户" if msg["role"] == "user" else ("助手" if msg["role"] == "assistant" else "系统")
        prompt += f"{role}：{msg['content']}\n"
    logger.info(f"传递给大模型的prompt：\n{prompt}")  # 调试日志
    
    # 提取最后一条用户消息作为查询
    user_messages = [msg["content"] for msg in messages if msg["role"] == "user"]
    query = user_messages[-1] if user_messages else prompt
    
    # 获取系统实例
    system = get_system_instance()
    
    if use_workflow:
        logger.info("使用工作流模式（LLM自主决定工具调用次数）")
        result = system.query_with_workflow(query, use_workflow=True)
        
        # 提取tool_calls，确保包含完整信息
        tool_calls = result.get("tool_calls", [])
        
        return {
            "response": result.get("response", ""),
            "use_workflow": True,
            "tools_used": result.get("analysis_summary", {}).get("tools_list", []),
            "workflow_steps": len(result.get("workflow_steps", [])),
            "retrieved_logs_count": result.get("retrieved_logs_count", 0),
            "tool_calls_detail": tool_calls  # 完整的工具调用详情（包含thought、result等）
        }
    else:
        logger.info("使用传统模式")
        result = system.query(query)
        time.sleep(0.5)
        
        return {
            "response": result.get("response", ""),
            "use_workflow": False,
            "tools_used": [],
            "workflow_steps": 0,
            "retrieved_logs_count": result.get("retrieval_stats", 0)
        }

def build_messages(context: str, user_input: str) -> list[dict]:
    """
    将数据库中的纯文本上下文 + 当前用户输入
    转换为结构化的多轮对话 messages 列表
    """
    messages = [{"role": "system", "content": "你是一个智能数据分析助手"}]

    if context.strip():
        for line in context.split("\n"):
            if line.startswith("用户："):
                messages.append({"role": "user", "content": line.replace("用户：", "").strip()})
            elif line.startswith("回复："):
                messages.append({"role": "assistant", "content": line.replace("回复：", "").strip()})

    # 加入当前用户输入
    messages.append({"role": "user", "content": user_input})
    return messages

def create_api_key(user: str) -> str:
    """创建 API Key 并保存到数据库"""
    key = APIKey.generate_key()
    expiry = time.time() + settings.TOKEN_EXPIRY_SECONDS
    
    api_key = APIKey.objects.create(
        key=key,
        user=user,
        expiry_time=expiry
    )
    
    # 创建对应的速率限制记录
    RateLimit.objects.create(
        api_key=api_key,
        reset_time=time.time() + settings.RATE_LIMIT_INTERVAL
    )
    
    return key

def validate_api_key(key_str: str) -> bool:
    """验证 API Key 是否存在且未过期"""
    try:
        api_key = APIKey.objects.get(key=key_str)
        if api_key.is_valid():
            return True
        else:
            api_key.delete()  # 删除过期key
            return False
    except APIKey.DoesNotExist:
        return False

def check_rate_limit(key_str: str) -> bool:
    """检查 API Key 的请求频率是否超过限制"""
    with rate_lock:
        try:
            # api_key = APIKey.objects.get(key=key_str)
            # rate_limit = RateLimit.objects.get(api_key=api_key)
            rate_limit = RateLimit.objects.select_related('api_key').get(api_key__key=key_str)
            
            current_time = time.time()
            if current_time > rate_limit.reset_time:
                rate_limit.count = 1
                rate_limit.reset_time = current_time + settings.RATE_LIMIT_INTERVAL
                rate_limit.save()
                return True
            elif rate_limit.count < settings.RATE_LIMIT_MAX:
                rate_limit.count += 1
                rate_limit.save()
                return True
            else:
                return False
        except RateLimit.DoesNotExist:
            # 如果速率限制记录不存在，创建一个新的
            try:
                current_time = time.time()
                api_key = APIKey.objects.get(key=key_str)
                RateLimit.objects.create(
                    api_key=api_key,
                    count=1,
                    reset_time=current_time + settings.RATE_LIMIT_INTERVAL
                )
                return True
            except APIKey.DoesNotExist:
                return False

# def get_or_create_session(session_id: str, user: APIKey) -> ConversationSession:
    # """获取或创建会话，关联当前用户（通过API Key）"""
    # session, created = ConversationSession.objects.get_or_create(
        # session_id=session_id,
        # user=user,  # 绑定用户
        # defaults={'context': ''}
    # )
    # return session

def get_or_create_session(session_id: str, user: APIKey) -> ConversationSession:
    """
    获取或创建用户的专属会话：
    - 若用户+session_id已存在 → 加载旧会话（保留历史）
    - 若不存在 → 创建新会话（空历史）
    """
    session, created = ConversationSession.objects.get_or_create(
        session_id=session_id,  # 匹配会话ID
        user=user,              # 匹配当前用户（关键！避免跨用户会话冲突）
        defaults={'context': ''}
    )
    # 调试日志：确认是否创建新会话（created=True 表示新会话）
    import logging
    logger = logging.getLogger(__name__)
    logger.info(f"会话 {session_id}（用户：{user.user}）{'创建新会话' if created else '加载旧会话'}")
    return session

def get_cached_reply(user_input: str, session_id: str, user: APIKey) -> str | None:
    """缓存键包含 session_id 和 user，避免跨会话冲突"""
    cache_key = f"reply:{user.user}:{session_id}:{hash(user_input)}"
    return cache.get(cache_key)

def set_cached_reply(user_input: str, reply: str, session_id: str, user: APIKey, timeout=3600):
    cache_key = f"reply:{user.user}:{session_id}:{hash(user_input)}"
    cache.set(cache_key, reply, timeout)


def generate_cache_key(original_key: str) -> str:
    """
    生成安全的缓存键。
    对原始字符串进行哈希处理，确保键长度固定且仅包含安全字符。
    """
    # 使用SHA256哈希函数生成固定长度的键（64位十六进制字符串）
    hash_obj = hashlib.sha256(original_key.encode('utf-8'))
    return hash_obj.hexdigest()
